import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:share_plus/share_plus.dart';
import 'package:spring_fairy/api/mood_track_api.dart';
import 'package:spring_fairy/footprints.dart';
import 'package:spring_fairy/local_notify.dart';
import 'package:spring_fairy/model/config.dart';
import 'package:latlong2/latlong.dart';
import 'package:spring_fairy/model/mood_track_point.dart';
import 'package:spring_fairy/model/mood_type.dart';
import 'package:spring_fairy/model/store.dart';
import 'package:spring_fairy/pages/mood_calendar_page.dart';
import 'package:spring_fairy/pages/record_point_list_page.dart';
import 'package:spring_fairy/pages/setting_page.dart';
import 'package:spring_fairy/util/amap_api.dart';
import 'package:spring_fairy/util/notify.dart';
import 'package:spring_fairy/widget/add_marked_point_dialog.dart';
import 'package:spring_fairy/widget/location_card.dart';
import 'package:spring_fairy/widget/marked_point_card.dart';
import 'package:spring_fairy/widget/mood_widget.dart';
import 'package:spring_fairy/widget/point_simple_card.dart';
import 'package:spring_fairy/widget/search_box.dart';
import 'package:spring_fairy/widget/three_finger_swipe_up_detector.dart';
import 'package:spring_fairy/widget/weather_card.dart';
import '../model/mood_track.dart';
import '../util/get_current_position.dart';

class RecordMoodTrackPage extends StatefulWidget {
  const RecordMoodTrackPage({super.key});

  @override
  State<RecordMoodTrackPage> createState() => _RecordMoodTrackPageState();
}

class _RecordMoodTrackPageState extends State<RecordMoodTrackPage> {
  late final MAP_POINT_FLAG_ID;
  static final Icon _LOCATION_ICON = Icon(Icons.my_location,color: AppConfig.PRIMARY_COLOR);

  late final FootPrints _footPrints;

  late final MapController _controller;
  late LatLng _currentLatlng = LatLng(30.232397,115.076457);

  //长时间驻留标记点
  final List<Marker> _marksWidget = [];
  //地图详情标记点
  final List<Marker> _tempMarksWidget = [];
  //已记录标记点
  final List<Marker> _recordPointWidget = [];

  late double _width,_height;
  int currentPageIndex = 0;
  MoodTrackPoint? _currentMoodTrackPoint;
  bool _showMoodTrackPoint = false;
  late MoodTrack moodTrack;
  late List<MoodTrackPoint> points;

  bool _hasInit = false;
  double _top = 500;
  double _left = 20;

  final GlobalKey _repaintKey = GlobalKey();
  final MoodTrackAPI _moodTrackAPI = MoodTrackAPI();

  double _currentZoom = 16.0;

  //当数据加载完成回调
  f() {
    this.moodTrack = Store.currentMoodTrack!;
    this.points = Store.getPoints().toList();

    MAP_POINT_FLAG_ID = Store.moodTypes().firstWhere((e) => e.name == 'location').id!;
    _updateMapRecordPoint();
  }

  @override
  void initState() {
     getCurrentPosition().then((position){
      _moveToCurrentPosition(position, null);
    });

    super.initState();
    _controller = MapController();
    _footPrints = FootPrints();
    _footPrints.startTracking();
    _footPrints.markingPointStream().listen((point) {
      if(point.id != null) {
        setState(() {
          if(point.moodLevel! <= 9) {
            point.moodLevel = point.moodLevel! + 1;
            _moodTrackAPI.updatePoint(point);
            _updateMapRecordPoint();
          }
        });
      } else {
        _moodTrackAPI.addPoint(moodTrack.id!, point).then((data) {
          if(data == null) {
            return ;
          }
          setState(() {
            Store.addMoodTrackPoint(data);
            _updateMapRecordPoint();
          });
          localNotify('添加新标记点', data.locationName ?? '位置地点');
        });
      }
    });

    initializeNotifications();
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
    _footPrints.stopTracking();
  }

  void _updateMapRecordPoint() {
    setState(() {
      _recordPointWidget.clear();
      Store.getPoints().forEach((ele) {

        double level = 1;
        if(ele.moodLevel != null && ele.moodLevel! >= 1) {
          level = ele.moodLevel! * 0.1;
        }

        while(level > 1) {
          level-=1;
        }
        _recordPointWidget.add(Marker(
            width: 80 ,
            height: 80,
            point: LatLng(ele.latitude!, ele.longitude!),
            child: TextButton(onPressed: (){
                _currentMoodTrackPoint = ele;
                setState(() {
                  _showMoodTrackPoint = true;
                });
            },child: Opacity(
              opacity: level,
              child: MoodWidget.location.lottie
            )))
        );
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    _width = MediaQuery.of(context).size.width;
    _height = MediaQuery.of(context).size.height;

    if(!_hasInit) {
      _left = _width * 0.8;
      _top = _height * 0.7;
      _hasInit = true;
    }
    return _buildBody(context);
  }

  Widget _buildBody(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: NavigationBar(
        onDestinationSelected: (int index) {
          setState(() {
            currentPageIndex = index;
          });
        },
        selectedIndex: currentPageIndex,
        destinations: <Widget>[
          NavigationDestination(
              icon: Icon(Icons.home),
              label: 'Home'),
          NavigationDestination(
              icon: Icon(Icons.list_alt),
              label: 'Record'),
          NavigationDestination(
              icon: Icon(Icons.calendar_month),
              label: 'Calendar'),
          NavigationDestination(
              icon: Icon(Icons.settings),
              label: 'Settings')
        ],
      ),
      body: Store.hasLoad
        ? _switchPage()
        : _loadDataWidget(context)
    );
  }

  Widget _loadDataWidget(BuildContext context) {
    return FutureBuilder(future: Store.loadData(), builder: (context,snapshot) {
      if(snapshot.hasError) {
        return Text("Network Error!");
      } else if(snapshot.connectionState == ConnectionState.done) {
        f();
        return _switchPage();
      } else {
        return CircularProgressIndicator();
      }
    });
  }

  Widget _switchPage() {
    switch(currentPageIndex) {
      case 0:
        return _flutterMapWidget(context);
      case 1:
        return RecordPointListPage(track: Store.currentMoodTrack!,points: Store.getPoints().toList());
      case 2:
        return MoodCalendarPage(data: Store.history());
      case 3:
        return SettingsPage();
      default:
        throw UnsupportedError("Not Page");
    }
  }

  Widget _flutterMapWidget(BuildContext context) {
    _updateMapRecordPoint();
    return ThreeFingerSwipeUpDetector(
      onThreeFingerSwipeUp: () {
        _share();
      },
      child: LayoutBuilder(builder: (context,constraints) {
        return Stack(
          children: [
            RepaintBoundary(
              key: _repaintKey,
              child: FlutterMap(
                mapController: _controller,
                options: MapOptions(
                    initialCenter: _currentLatlng, // Center the map over London
                    initialZoom: _currentZoom,
                    onLongPress: (tapPosition, latlng) {
                      _onLongPress(latlng);
                    },
                    onTap: (_, latlog) {
                      if (_showMoodTrackPoint) {
                        setState(() {
                          _showMoodTrackPoint = false;
                        });
                      }
                    }
                ),
                children: [
                  TileLayer( // Bring your own tiles
                    urlTemplate: AppConfig.LAYERS_PATH,
                  ),
                  MarkerLayer(markers: _marksWidget),
                  MarkerLayer(markers: _tempMarksWidget),
                  MarkerLayer(markers: _recordPointWidget),
                  if(_showMoodTrackPoint && _currentMoodTrackPoint != null)
                    Stack(
                      children: [Align(
                          alignment: Alignment.topCenter,
                          child: Padding(
                            padding: const EdgeInsets.only(top: 32),
                            child: SizedBox(
                              width: _width * 0.7,
                                height: _height * 0.6,
                                child: PointSimpleCard(point: _currentMoodTrackPoint!)),
                          )
                      )
                      ],
                    ),
                ],
              ),
            ),
            Positioned(
              top: _top,
              left: _left,
              child: GestureDetector(
                onPanUpdate: (details) {
                  setState(() {
                    _left = (_left + details.delta.dx).clamp(0.0, constraints.maxWidth - 56); // 56 = FAB 宽
                    _top = (_top + details.delta.dy).clamp(0.0, constraints.maxHeight - 56);   // 56 = FAB 高
                  });
                },
                onLongPress: () {
                  _onLongPress(_currentLatlng);
                },
                child: FloatingActionButton(
                  onPressed: () {
                    getCurrentPosition().then((e) =>
                        _moveToCurrentPosition(e, null));
                  },
                  child: const Icon(Icons.location_on),
                ),
              ),
            ),
            Align(
              alignment: Alignment.bottomLeft,
              child: Padding(
                padding: const EdgeInsets.only(bottom: 60),
                child: WeatherCard(
                    weather: Store.weatherData?.weather ?? '阴天',
                    temperature: Store.weatherData?.temperature ?? 22,
                    icon: Icons.grain),
              ),
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Container(
                    width: _width * 0.8,
                    child: AnimatedSearchBar(onSearch: _onSearchAddress)),
              ),
            )
          ],
        );
      }),
    );
  }

  void _moveToCurrentPosition(Position? position,LatLng? latlng) {
    if (position == null && latlng == null) {
      return;
    }

    if (position != null) {
      setState(() {
        _currentLatlng = LatLng(position.latitude, position.longitude);
      });
      _controller.move(LatLng(position.latitude, position.longitude), _currentZoom);
     } else {
      setState(() {
        _currentLatlng = latlng!;
        _controller.move(latlng, _currentZoom);
      });
  }

    setState(() {
      if(_marksWidget.isEmpty) {
        _marksWidget.add(Marker(
            point: _currentLatlng,
            child: _LOCATION_ICON));
      } else {
        _marksWidget[0] = Marker(point: _currentLatlng, child: _LOCATION_ICON);
      }
    });
}

  void _onLongPress(LatLng latlng) {
    getAddressByLatlng(latlng).then((addressMap) {
      if(addressMap == null) {
        return ;
      }

      String addressName = addressMap['regeocode']['formatted_address'].toString();

      Marker marker = Marker(point: latlng,
          width: _width * 0.45,
          height: _height * 0.30,
          child: LocationCard(
          location: latlng,
          locationName: addressName,
          onAdd: (){
            _onAddMark(latlng,addressName);
          },
          onCancel: (){
            setState(() {
              _tempMarksWidget.clear();
            });
          }));

      setState(() {
        _tempMarksWidget.clear();
        _tempMarksWidget.add(marker);
      });
    });

    // _showEmotionSelector(context, latlng);
  }

  void _onAddMark(LatLng latlng,String addressName) async {
    //添加标记点逻辑

    //获取天气、温度
    var weatherMap = await getWeather(latlng);
    String weather = weatherMap['forecasts'][0]['casts'][0]['dayweather'];
    double? weatherTemp = double.tryParse(weatherMap['forecasts'][0]['casts'][0]['daytemp_float'].toString());

    MoodTrackPoint point = MoodTrackPoint(
      latitude: latlng.latitude,
      longitude: latlng.longitude,
      createdAt: DateTime.now(),
      locationName: addressName,
      moodLevel: 1,
      moodTime: DateTime.now(),
      weather: weather,
      temperature: weatherTemp
    );

    point = await showDialog(context: context, builder: (_) => AddMarkedPointDialog(moodTrackPoint: point,moodTrack: moodTrack));
    _updateMapRecordPoint();
  }

  void _showEmotionSelector(BuildContext context, LatLng position) async {
    final selectedEmotion = await showModalBottomSheet<String>(
      context: context,
      builder: (context) => Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          ListTile(leading: Icon(Icons.sentiment_satisfied), title: Text("开心"), onTap: () => Navigator.pop(context, 'happy')),
          ListTile(leading: Icon(Icons.sentiment_dissatisfied), title: Text("难过"), onTap: () => Navigator.pop(context, 'sad')),
          ListTile(leading: Icon(Icons.sentiment_very_dissatisfied), title: Text("生气"), onTap: () => Navigator.pop(context, 'angry')),
        ],
      ),
    );

    if (selectedEmotion != null) {
      _addEmotionMarker(position, selectedEmotion);
    }
  }

  void _addEmotionMarker(LatLng position, String emotion) {
    IconData icon;
    Color color;

    switch (emotion) {
      case 'happy':
        icon = Icons.sentiment_satisfied;
        color = Colors.yellow;
        break;
      case 'sad':
        icon = Icons.sentiment_dissatisfied;
        color = Colors.blue;
        break;
      case 'angry':
        icon = Icons.sentiment_very_dissatisfied;
        color = Colors.red;
        break;
      default:
        icon = Icons.location_on;
        color = Colors.grey;
    }

    setState(() {
      _marksWidget.add(
        Marker(
          point: position,
          width: 40,
          height: 40,
          child: Icon(icon, size: 40, color: color),
        ),
      );
    });
  }

  void _onSearchAddress(String query) {
    searchDetailAddress(query, null).then((addressMap) {
      if(addressMap == null) {
        return ;
      }
      String position = addressMap['geocodes'][0]['location'];
      var splits = position.trim().split(',');
      LatLng latLng = LatLng(double.parse(splits[1].trim().toString()), double.parse(splits[0].trim().toString()));
      _moveToCurrentPosition(null, latLng);

      String addressName = addressMap['geocodes'][0]['formatted_address'].toString();

      Marker marker = Marker(point: latLng,
          width: _width * 0.45,
          height: _height * 0.30,
          child: LocationCard(
              location: latLng,
              locationName: addressName,
              onAdd: (){
                _onAddMark(latLng,addressName);
              },
              onCancel: (){
                setState(() {
                  _tempMarksWidget.clear();
                });
              }));

      //在地图中显示该标记点
      setState(() {
        _tempMarksWidget.clear();
        _tempMarksWidget.add(marker);
      });

    });
  }

  void _share() async {
    final boundary = _repaintKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
    final image = await boundary.toImage(pixelRatio: 3.0);
    final byteData = await image.toByteData(format: ImageByteFormat.png);
    final pngBytes = byteData!.buffer.asUint8List();
    var params = ShareParams(
      files: [XFile.fromData(pngBytes,mimeType: 'image/png')],
    );
    SharePlus.instance.share(params);
  }
}
